/*-------------------------------------------------------------------------
FileName     : AliasRef.h
Description  : 对象的别名引用类
remark       : 更方便地对某些对象设备别名，后续通过别名查找
Modification :
--------------------------------------------------------------------------
   1、Date  2020-08-20       create     hejl 
-------------------------------------------------------------------------*/
#ifndef _ALIAS_REF_H_
#define _ALIAS_REF_H_
#include <string>
#include <map>
#include <set>
#include <mutex>

using namespace std;

template <class T>
class AliasRef
{
private:
    map<string, T> aliasRef;
    map<T, set<string>> nameSet;
    mutex refMtx;

public:
    AliasRef(){}
    ~AliasRef(){}

    bool addAlias(const string &name, T t)
    {
        lock_guard<mutex> lock(refMtx);
        auto par = nameSet[t].insert(name);
        if (par.second)
        {
            aliasRef[name] = t;
            return true;
        }

        return false;
    }

    void delAlias(const string &name)
    {
        lock_guard<mutex> lock(refMtx);
        auto itr = aliasRef.find(name);
        if (itr != aliasRef.end())
        {
            auto itr2 = nameSet.find(itr->second);
            aliasRef.erase(name);
            set<string> &nset = itr2->second;
            nset.erase(name);
            if (nset.empty())
            {
                nameSet.erase(itr2);
            }
        }
    }

    void delAlias(T t)
    {
        lock_guard<mutex> lock(refMtx);
        auto itr = nameSet.find(t);
        if (itr != nameSet.end())
        {
            for (auto name : itr->second)
            {
                aliasRef.erase(name);
            }

            nameSet.erase(itr);
        }
    }

    T find(const string &name)
    {
        lock_guard<mutex> lock(refMtx);
        auto itr = aliasRef.find(name);
        if (itr != aliasRef.end())
        {
            T t = itr->second;
            return t;
        }

        return 0;
    }
};

#endif